fix(local-cli): AppleScript 被拒时降级到 Launch Services#486
Conversation
daemon 通过 PM2/launchd 后台运行时,osascript 发送 Apple事件的负责进程是
node/PM2 而非 iTerm,macOS TCC 永不弹 Automation 授权弹窗,导致 -1743
错误且自动化设置里找不到 iTerm/Terminal。
新增 openViaCommandFile 降级路径:AppleScript 全部失败后,将命令写入临时
.command 文件并通过 `open -a iTerm` 打开。Launch Services 无需 Automation
权限,覆盖后台 daemon 场景。
影响面:
- 仅影响 macOS 本机 CLI 打开流程(openLocalCliInIterm)
- AppleScript 成功时行为不变,仅在全部失败后触发降级
- Linux 路径不受影响(darwin 平台检查在前)
- 新增 runOpenCommand 依赖注入点,默认走 spawnSync('open', ['-a', 'iTerm', path])
测试:新增 2 个单测覆盖降级成功与降级失败场景,原有 5 个 osascript
调用断言保持不变。vitest run --project unit test/local-cli-opener.test.ts
(25 passed) + test/card-handler-open-local-cli.test.ts (19 passed)。
Review 总结感谢 @47seek 贡献这个修复!方案方向正确——daemon 在 PM2/launchd 后台运行时 TCC 永不弹 Automation 授权弹窗,用 Launch Services 降级是合理思路。代码结构清晰,依赖注入设计好,测试覆盖到位。 我们做了两轮独立 review,发现以下问题,建议修复后再合入: 🔴 阻塞:成功路径永久泄漏临时目录
注意:不能简单短延迟 timer 清理——Launch Services 打开是异步的,且 iTerm 对外部脚本默认先弹"OK to run …?"确认框,用户可能很久后才确认或取消。建议让 🟡 建议同 PR 补齐
🟢 额外建议
验证结果
另外,botmux 项目在飞书有开发者协作群,方便日常沟通、方案讨论和快速 review。如果你愿意加入协作,可以私信我(@deepcoldy)获取入群方式。期待你的更新!🚀 |
|
已按 review 意见补齐并完成复查,当前 head 为
验证结果:相关 2 个测试文件共 46 tests passed, 当前 CI run 是 补充:已拉取 GitHub 生成的 merge ref |
改了什么
macOS 本机 CLI 打开流程在全部 AppleScript 尝试失败后,新增 Launch Services 降级路径:
0700的临时.command文件/usr/bin/open,依次尝试 iTerm 与 Terminal.app 的 bundle id,不阻塞 daemon 事件循环mkdtemp生成的精确六位后缀目录,避免误删同前缀的用户目录为什么
当 daemon 由 PM2/launchd 后台运行时,
osascript发送 Apple Event 的负责进程是 node/PM2,而不是启动 daemon 的 iTerm。macOS TCC 因此不会向 iTerm 弹出 Automation 授权,AppleScript 会持续返回-1743。open走 Launch Services,不需要 Automation 权限,可以覆盖这个后台 daemon 场景。影响面
openLocalCliInIterm,并且只在现有 5 次 AppleScript 尝试全部失败后执行测试验证
回归测试额外验证:
.command文件权限、自清理与 24 小时 stale sweep注:未切换当前 live daemon;真实 macOS PM2/launchd 下的 TCC 与终端确认框交互仍需手动 click-through 验证。